import {
  BadRequestError,
  Body,
  BodyParam,
  Delete,
  Get,
  JsonController,
  Param,
  Post,
  QueryParam,
} from "routing-controllers";
import { Service } from "typedi";
import { UserService } from "../services";
import {
  sys_meta_data,
  sys_meta_data_property,
  sys_meta_form,
  sys_meta_view,
  sys_meta_view_property,
  user,
} from "@prisma/client";
import { Result } from "app/utils/result";
import { sign } from "app/utils/auth";
import { ViewParamReq, Filter, FilterVal, ViewParam, ViewParamField } from "./ViewParam";

@Service()
@JsonController("/user")
export class UserController {
  // 构造器
  constructor(private userService: UserService) {
    this.userService = new UserService();
  }

  // 列表通用接口
  @Post("/meta/list")
  async metaListQuery(@Body() requestData: ViewParamReq) {
    // console.log("requestData:", requestData)
    // 根据视图查询数据

    // 根据视图id查找视图
    let view: sys_meta_view = await this.userService.queryViewById({ id: requestData.id });
    let viewParam: ViewParam = JSON.parse(view.view_param);
    // 遍历视图中的显示属性
    // viewParam.templateContainerList.forEach(f => {
    //     let fields: ViewParamField[] = f.fieldList;
    //     fields.forEach(ff => {
    //         console.log(ff.propertyName, ff.metaPropertyId)
    //     })
    // })

    // 读取视图的属性列表
    let viewProps: sys_meta_view_property[] = await this.userService.queryViewPropById({ id: requestData.id });
    // 根据object_ref_id得到所有的引用属性， 需要像外键一样去读取它的数据
    // 过滤所有的引用id
    let refs: any = viewProps.filter((v) => (v.object_reference_id ? true : false)).map((v) => v.object_reference_id);
    // 读取meta_data_property的属性数据
    let metaDataRefs: sys_meta_data[] = [];
    for (let i = 0; i < refs.length; i++) {
      // 读取metaData的属性
      let dataProp: sys_meta_data_property = await this.userService.queryDataPropById({ id: refs[i] });
      // 根据object_ref_id查找具体的数据表
      let metaData: sys_meta_data = await this.userService.queryDataById({ id: dataProp.object_reference_id });
      metaDataRefs.push(metaData);
    }

    // 读取视图关联的用户表的数据
    let metaData: sys_meta_data = await this.userService.queryDataById({ id: view.main_object_id });
    // 动态的读取表数据
    let list = await this.userService.queryAllByMeta(metaData.key_name);

    // 引用数据转换
    for (let i = 0; i < list.length; i++) {
      let user = list[i];
      for (let j = 0; j < metaDataRefs.length; j++) {
        console.log("🚀 ~ UserController ~ metaListQuery ~ metaDataRefs[j]:", metaDataRefs[j]);
        let table = metaDataRefs[j]?.key_name;
        // 读取引用属性的数据并赋值
        user[table] = table && (await this.userService.queryAllByMetaAndId(table, user[table]));
      }
    }

    return Result.ok({ list, viewParam });
  }

  @Get("/meta/form")
  async metaFormQuery(@QueryParam("formId") formId: number) {
    let metaForm: sys_meta_form = await this.userService.queryFormById({ id: formId });
    // 需要将json字符串转换
    metaForm.form_param = JSON.parse(metaForm.form_param);

    return Result.ok(metaForm);
  }

  @Post("/create")
  async createAll(@Body() users: user[]) {
    for (let i = 0; i < users.length; i++) {
      await this.userService.create(users[i]);
    }
    return Result.ok(null);
  }

  @Get("/all")
  async all() {
    let result: user[] = await this.userService.all();
    return Result.ok(result);
  }

  @Delete("/delete/:id")
  async remove(@Param("id") id: number) {
    let r = await this.userService.delete(id);
    return Result.ok(r);
  }

  @Get("/list")
  async queryByPage(@QueryParam("pageNo") pageNo: number, @QueryParam("pageSize") pageSize: number) {
    // skip跳过多少页
    // console.log(pageNo, pageSize)
    let result = await this.userService.page({ skip: Number((pageNo - 1) * pageSize), take: Number(pageSize) });
    return Result.ok(result);
  }

  @Post("/create-update")
  async createAndUpdate(@Body() user: user) {
    if (user.id) {
      // update
      let res = await this.userService.update({ data: user, where: { id: user.id } });
      return Result.ok(res);
    }
    // insert
    let res = await this.userService.create(user);
    return Result.ok(res);
  }

  @Get("/query-name")
  async queryByName(@QueryParam("name") name: string) {
    let res = await this.userService.queryUserByName(name);
    return Result.ok(res);
  }

  @Post("/login")
  async login(@BodyParam("username") username: string, @BodyParam("password") password: string) {
    if (!username || !password) {
      throw new BadRequestError("用户名或密码不存在");
    }
    let { user, role } = await this.userService.queryByAccount({ username });
    console.log(user, role);
    // 判断传入的密码与db的一致
    if (user && user.password === password) {
      // generate token
      user.password = null;
      const token = sign({ account: username, user: String(user.id) });
      return Result.ok({ token, user, role });
    } else {
      return Result.fail("登录失败，请检查账号密码");
    }
  }
}
